package com.imax.emap.overlay
{
	import com.imax.emap.core.Bounds;
	import com.imax.emap.mapProvider.IMapProvider;
	
	import mx.core.ClassFactory;
	import mx.core.IDataRenderer;
	import mx.core.IFactory;
	import mx.core.UIComponent;

	public class TileLayerOverlay extends UIComponent implements IOverlay
	{
		private var mapProvider:IMapProvider;
		private var _itemRenderer:IFactory;
		private var tileSize:Number;
		
		/**
		 * 地图瓦片的范围 
		 */		
		private var tileBound:Bounds;
		/**
		 * 缩放等级 
		 */		
		private var zoom:int;
		
		/**
		 * 构造函数 
		 * @param _mapProvider 地图提供商类
		 * 
		 */		
		public function TileLayerOverlay(_mapProvider:IMapProvider){
			super();
			_itemRenderer = new ClassFactory(MapTile);
			this.mapProvider = _mapProvider;
			tileSize = mapProvider.getTileSize();
		}
		
		/**
		 * 地图可视范围改变，当地图拖拽 setCenter 缩放等都会调用此函数
		 * @param _viewBound 可视范围
		 * @param _zoom 缩放等级
		 * 
		 */		
		public function viewBoundChanged(_viewBound:Bounds,_zoom:int):void{
			//地图瓦片的范围，跟_viewBound完全不同的了，这个是关乎地图瓦片坐标的范围`
			var _tileBound:Bounds = new Bounds();
			//某缩放比例下，瓦片层的宽度
			var tileLayerWidth:Number = mapProvider.getProjection().getTileWidth(_zoom);
			//某缩放比例下，瓦片层的高度
			var tileLayerHeight:Number = mapProvider.getProjection().getTileHeight(_zoom);
			//从像素, 到Tile的Column, row的近似值.需要显示的图片比_viewBound的大一点
			
			//tile的x不可能小于0啊大哥
			_tileBound.left = Math.floor((_viewBound.left-tileSize/2)/tileSize);
			_tileBound.right = Math.floor((_viewBound.right+tileSize/2)/tileSize);
			
			//tile的y不可能小于0啊大哥
			_tileBound.top = Math.floor((_viewBound.top-tileSize/2)/tileSize);
			_tileBound.bottom = Math.floor((_viewBound.bottom+tileSize/2)/tileSize);
			//trace(_tileBound.toString());
			if(this.zoom != _zoom){
				this.zoom = _zoom;
				this.removeAllImages();
			}
			//tileBound = _tileBound;
			trace("可视范围",_viewBound.toString());
			trace("瓦片范围",_tileBound.toString());
			
			
			this.loadImages(_tileBound, _zoom);
			this.removeImages(_tileBound, _zoom);	
		}
		
		/**
		 * 加载图片
		 * @param toShow 需要显示的可视范围
		 * @param zoom 缩放等级
		 * 
		 */		
		private function loadImages(toShow:Bounds, _zoom:int):void{
			//make sure tiles in toShow aria is inUse.
			for(var i:Number= toShow.left; i <= toShow.right; i++){
				for(var m:Number = toShow.top; m <= toShow.bottom; m++){
					var _tileData:Object = {x : i, y : m, z: _zoom};
					//check if exists.
					var tile:MapTile;
					tile = getTileByID(i + "_" + m + "_" + _zoom);
					if(!tile){
						tile = _itemRenderer.newInstance();
						addChild(tile);
						IDataRenderer(tile).data = _tileData;
						MapTile(tile).provider = mapProvider;
					}
					
					tile.inUse = true;
				}
			}

			invalidateDisplayList();						
		}
		
		/**
		 * 通过ID获得图片,ID的格式为
		 * @param id 地图瓦片的id字符串，以x_y_zoom格式
		 * @return 地图瓦片的类
		 * 
		 */		
		private function getTileByID(id:String):MapTile{
			for(var i:int = 0; i < this.numChildren;i++) {
				var tile:MapTile = this.getChildAt(i) as MapTile;
				if(tile.id==id){
					return tile;
				}
			}
			return null;
		}
		
		/**
		 *  删除显示不到的图片
		 * @param toShow 需要显示的区域
		 * @param zoom 缩放等级
		 * 
		 */		
		private function removeImages(toShow:Bounds, _zoom:int):void{
			//trace("Before: " + this.numChildren);
			for(var i:int = 0; i < this.numChildren;i++) {
				var tile:MapTile = this.getChildAt(i) as MapTile;
				if(!tile.inUse){
					tile.cancleLoad();
					this.removeChildAt(i);
				}
			}
			//trace("After: " + this.numChildren);
			
		}
		
		/**
		 * 删除所有地图瓦片图片
		 * 
		 */		
		private function removeAllImages():void{
			//或许会异常
			/* for(var m:int = 0; m < this.numChildren;m++) {
				this.removeChildAt(m);
			} */
			
			//最好不要这样删除.
			while(this.numChildren!=0){
				this.removeChildAt(0);
			}
			
			//还可以从后向前删除...
			//还可以...
		}
		
		/**
		 * 将所有图片设成false，以便删除不在可视范围的地图瓦片
		 * 
		 */		
		private function setFlase():void{
			for(var i:int = 0; i < this.numChildren;i++) {
				var tile:MapTile = this.getChildAt(i) as MapTile;
				tile.inUse = false;
			}
		}
		
		/**
		 * 更新视图，显示所有图片并设定每张图片的像素坐标
		 * @param unscaledWidth
		 * @param unscaledHeight
		 * 
		 */		
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
			for(var i:int = 0; i < this.numChildren;i++) {
				var mapTile:MapTile = MapTile(this.getChildAt(i));
				mapTile.x = mapTile.data.x * tileSize;
				mapTile.y = mapTile.data.y * tileSize;
			}
		}
	}
}